﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using WeChatSDK.Common;
using WeChatSDK.Common.Enums.Http;
using WeChatSDK.RequestComponent.Http;
using WeChatSDK.WeChatDto.Request.Http;
using WeChatSDK.WeChatDto.User;
using WeChatSDK.WeChatServiceComponent.Conversation.BaseSupport;

namespace WeChatSDK.WeChatServiceComponent.User
{
    /// <summary>
    /// 用户管理服务
    /// </summary>
    public class WeChatUserService
    {
        private readonly HttpHandle httpHandle;
        public WeChatUserService()
        {
            this.httpHandle = new HttpHandle();
        }
        #region 用户标签管理
        /// <summary>
        /// 添加用户标签
        /// </summary>
        /// <param name="userTagDto">用户标签</param>
        /// <returns></returns>
        public HttpResponseDto AddUserTag(UserTagDto userTagDto)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/create?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, userTagDto, MethodType.POST);
        }
        /// <summary>
        /// 修改用户标签
        /// </summary>
        /// <param name="userTagDto">用户标签</param>
        /// <returns></returns>
        public HttpResponseDto UpdateUserTag(UserTagDto userTagDto)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/update?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, userTagDto, MethodType.POST);
        }
        /// <summary>
        /// 获取公众号已创建的标签
        /// </summary>
        /// <returns></returns>
        public HttpResponseDto GetUserTag()
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/get?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, null, MethodType.GET);
        }
        /// <summary>
        /// 获取公众号已创建的标签
        /// </summary>
        /// <returns></returns>
        public HttpResponseDto DeleteUserTag(UserTagDto userTagDto)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/delete?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, userTagDto, MethodType.POST);
        }
        /// <summary>
        /// 获取标签下粉丝列表
        /// </summary>
        /// <param name="tagId">标签Id</param>
        /// <param name="nextOpenId">第一个拉取的OPENID，不填默认从头开始拉取</param>
        /// <returns></returns>
        public HttpResponseDto GetTagFans(long tagId, string nextOpenId)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, new { Tagid = tagId, NextOpenid = nextOpenId }, MethodType.POST);
        }
        #endregion

        #region 用户标签操作
        /// <summary>
        /// 批量为用户打标签
        /// 备注：标签功能目前支持公众号为用户打上最多20个标签。
        /// </summary>
        /// <param name="tagId">标签Id</param>
        /// <param name="openids">用户Openid数组</param>
        /// <returns></returns>
        public HttpResponseDto BatchTagging(long tagId, List<string> openids)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, new { Tagid = tagId, OpenidList = openids.ToArray() }, MethodType.POST);
        }
        /// <summary>
        /// 批量为用户取消标签
        /// </summary>
        /// <param name="tagId">标签Id</param>
        /// <param name="openids">用户Openid数组</param>
        /// <returns></returns>
        public HttpResponseDto BatchUnTagging(long tagId, List<string> openids)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, new { Tagid = tagId, OpenidList = openids.ToArray() }, MethodType.POST);
        }
        /// <summary>
        /// 获取用户身上的标签列表
        /// </summary>
        /// <param name="openId">用户OpenId</param>
        /// <returns></returns>
        public HttpResponseDto BatchUnTagging(string openId)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/getidlist?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, new { Openid = openId }, MethodType.POST);
        }
        #endregion

        #region 设置用户备注名
        /// <summary>
        /// 设置用户备注名
        /// </summary>
        /// <param name="openId">用户OPendId</param>
        /// <param name="remarkName">用户备注名</param>
        /// <returns></returns>
        public HttpResponseDto UpdateUserNameRemark(string openId, string remarkName)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, new { Openid = openId, Remark = remarkName }, MethodType.POST);
        }
        #endregion

        #region 用户基本信息


        /// <summary>
        /// 登录凭证校验
        /// </summary>
        /// <param name="code">临时登录凭证code</param>
        /// <returns></returns>
        public HttpResponseDto Login(string code)
        {
            string url = string.Format("https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code", WeChatInfo.AppId, WeChatInfo.Secret, code);
            return SendRequest(url, null, MethodType.GET);
        }
        /// <summary>
        /// 登录凭证校验(小程序使用)
        /// </summary>
        /// <param name="code">临时登录凭证code</param>
        /// <returns></returns>
        public HttpResponseDto MinProgramLogin(string code)
        {
            string url = string.Format("https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code", WeChatInfo.MiniProgramAppId, WeChatInfo.MiniProgramAppSecret, code);
            return SendRequest(url, null, MethodType.GET);
        }
        /// <summary>
        /// 获取用户基本信息
        /// </summary>
        /// <param name="openId">用户OpenId</param>
        /// <param name="lang">地区语言版本</param>
        /// <returns>
        /// {
        ///    "subscribe": 1, 
        ///    "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", 
        ///    "nickname": "Band", 
        ///    "sex": 1, 
        ///    "language": "zh_CN", 
        ///    "city": "广州", 
        ///    "province": "广东", 
        ///    "country": "中国", 
        ///    "headimgurl":"http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
        ///    "subscribe_time": 1382694957,
        ///    "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
        ///    "remark": "",
        ///    "groupid": 0,
        ///    "tagid_list":[128,2],
        ///    "subscribe_scene": "ADD_SCENE_QR_CODE",
        ///    "qr_scene": 98765,
        ///    "qr_scene_str": ""
        ///}
        ///</returns>
        public HttpResponseDto GetUserInfoByOpenId(string openId, string lang = "zh_CN")
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang={2}", new BaseSupportService().CreateAccessToken().AccessToken, openId, lang);
            return SendRequest(url, null, MethodType.GET);
        }
        /// <summary>
        /// 批量获取用户信息
        /// </summary>
        /// <param name="openIds">用户OpenIds</param>
        /// <param name="lang">地区语言版本</param>
        /// <returns>
        /// {
        ///   "user_info_list": [
        ///       {
        ///           "subscribe": 1,
        ///           "openid": "otvxTs4dckWG7imySrJd6jSi0CWE",
        ///           "nickname": "iWithery",
        ///           "sex": 1,
        ///           "language": "zh_CN",
        ///           "city": "揭阳",
        ///           "province": "广东",
        ///           "country": "中国",
        ///
        ///           "headimgurl": "http://thirdwx.qlogo.cn/mmopen/xbIQx1GRqdvyqkMMhEaGOX802l1CyqMJNgUzKP8MeAeHFicRDSnZH7FY4XB7p8XHXIf6uJA2SCunTPicGKezDC4saKISzRj3nz/0",
        ///
        ///          "subscribe_time": 1434093047,
        ///           "unionid": "oR5GjjgEhCMJFyzaVZdrxZ2zRRF4",
        ///           "remark": "",
        ///
        ///           "groupid": 0,
        ///           "tagid_list":[128,2],
        ///           "subscribe_scene": "ADD_SCENE_QR_CODE",
        ///           "qr_scene": 98765,
        ///           "qr_scene_str": ""
        ///
        ///      }, 
        ///       {
        ///           "subscribe": 0, 
        ///           "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg"
        ///       }
        ///   ]
        ///}
        /// </returns>
        public HttpResponseDto GetUserInfoByOpenIds(List<string> openIds, string lang = "zh_CN")
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            List<object> userList = new List<object>();

            foreach (string openid in openIds)
            {
                object user = new { Openid = openid, Lang = lang };
                userList.Add(user);
            }
            return SendRequest(url, new { UserList = userList.ToArray() }, MethodType.POST);
        }
        #endregion

        #region 获取关注者Openid列表
        /// <summary>
        /// 获取关注者Openid列表
        /// 备注：每次最多10000个，多个时
        /// </summary>
        /// <param name="nextOpenId">下一次开始的openId</param>
        /// <returns>
        /// {
        ///     "total":2,
        ///     "count":2,
        ///     "data":{
        ///         "openid":["OPENID1","OPENID2"]
        ///     },
        ///     "next_openid":"NEXT_OPENID"
        /// }
        ///</returns>
        public HttpResponseDto GetUserOpenIdList(string nextOpenId)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            if (!string.IsNullOrWhiteSpace(nextOpenId))
            {
                url += string.Format("&next_openid={0}", nextOpenId);
            }
            return SendRequest(url, null, MethodType.GET);
        }
        #endregion

        #region 黑名单管理
        /// <summary>
        /// 获取公众号黑名单列表
        /// </summary>
        /// <param name="nextOpenId">开始的OpenId</param>
        /// <returns>
        /// {
        /// "total":23000,
        /// "count":10000,
        /// "data":{"
        ///    openid":[
        ///       "OPENID1",
        ///       "OPENID2",
        ///       ...,
        ///       "OPENID10000"
        ///    ]
        ///  },
        ///  "next_openid":"OPENID10000"
        ///}
        /// </returns>
        public HttpResponseDto GetBlackUserList(string nextOpenId)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/members/getblacklist?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            object beginOpenid = null;
            if (!string.IsNullOrWhiteSpace(nextOpenId))
            {
                beginOpenid = new { BeginOpenid = nextOpenId };
            }
            return SendRequest(url, beginOpenid, MethodType.POST);
        }
        /// <summary>
        /// 批量拉黑用户
        /// </summary>
        /// <param name="openIds">用户OpenIds</param>
        /// <returns>{ "errcode": 0,"errmsg": "ok"}</returns>
        public HttpResponseDto BatchBlackUser(List<string> openIds)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/members/batchblacklist?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, new { OpenidList = openIds.ToArray() }, MethodType.POST);
        }
        /// <summary>
        /// 批量取消拉黑用户
        /// </summary>
        /// <param name="openIds">用户OpenIds</param>
        /// <returns>{ "errcode": 0,"errmsg": "ok"}</returns>
        public HttpResponseDto BatchUnBlackUser(List<string> openIds)
        {
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/tags/members/batchunblacklist?access_token={0}", new BaseSupportService().CreateAccessToken().AccessToken);
            return SendRequest(url, new { OpenidList = openIds.ToArray() }, MethodType.POST);
        }
        #endregion

        #region 执行发送消息
        /// <summary>
        /// 执行发送消息
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="obj">对象信息</param>
        /// <returns></returns>
        private HttpResponseDto SendRequest(string url, object obj, MethodType methodType)
        {
            HttpRequestDto httpRequestDto = new HttpRequestDto();
            httpRequestDto.Url = url;
            httpRequestDto.Headers.Add("Content-Type", "application/json");
            if (methodType == MethodType.POST || methodType == MethodType.PUT)
            {
                httpRequestDto.Content = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(obj, WeChatGeneral.JsonSerializerSettings));
            }
            httpRequestDto.Method = methodType;
            httpRequestDto.ContentType = FormatType.JSON;
            return httpHandle.WebSendRequest(httpRequestDto);
        }
        #endregion
    }
}
